import * as Cesium from "cesium";
import AmapMercatorTilingScheme from "./amaptiling";
import { mainStore } from "../store/index";
import { toRaw } from "vue";
import { ElMessage } from "element-plus";
import fluidPolyline from "./migrate";
import fluidPolylinetrend from "./trend";
Cesium.Ion.defaultAccessToken =
    "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIwOTc0OWZiMC1kYWFkLTQ3Y2QtODQyNC0wNTdkMTdmMTk4MTEiLCJpZCI6MjIzMTMsImlhdCI6MTYwMjUzOTUxNH0.r18dBOtxmRRuiYcogILHfk3TN7lGrgOfTDSxIYxO9hY";

var viewer = null;
var viewer2 = null;
var tiemSfa = null;
var worldTerrain = Cesium.createWorldTerrain({
    requestWaterMask: true,
    requestVertexNormals: true,
});
let wapworldToken = "4f84dc2cfc78b3442152aaa133229c3b";
// 服务域名
var tdtUrl = "https://t{s}.tianditu.gov.cn/";
// 服务负载子域
var subdomains = ["0", "1", "2", "3", "4", "5", "6", "7"];

function setviewer() {
    viewer = new Cesium.Viewer("cesiumContainer", {
        animation: false, //左下角控制动画
        baseLayerPicker: false, //右上角图层选择器
        fullscreenButton: false,
        geocoder: false, //右上角搜索
        homeButton: false,
        infoBox: false,
        scene3DOnly: true, //仅仅显示3d,可隐藏右上角2d和3d按钮
        selectionoIndicatr: false,
        timeline: true, //最下面时间轴
        navigationHelpButton: false, //右上角帮助按钮
        navigationInstructionsInitiallyVisibl: false,
        useDefaultRenderLoop: true,
        showRenderLoopErrors: true,
        projectionPicker: false,
        shouldAnimate: true,
        terrainProvider: worldTerrain,
        // terrainProvider: new Cesium.CesiumTerrainProvider({
        //     url: "https://data.marsgis.cn/terrain",
        // }),
        // terrainProvider: new Cesium.CesiumTerrainProvider({url:`http://t7.tianditu.gov.cn/vec_c/wmts?tk=${wapworldToken}`})
    });
    var m_temp_source = new Cesium.CustomDataSource("tempSourceLayer");
    viewer.dataSources.add(m_temp_source);

    mapset(viewer);
    layset(viewer);
    leftclick();
    courser();
    viewer2 = new Cesium.Viewer("cesiumContainer2", {
        animation: false, //左下角控制动画
        baseLayerPicker: false, //右上角图层选择器
        fullscreenButton: false,
        geocoder: false, //右上角搜索
        homeButton: false,
        infoBox: false,
        scene3DOnly: true, //仅仅显示3d,可隐藏右上角2d和3d按钮
        selectionoIndicatr: false,
        timeline: true, //最下面时间轴
        navigationHelpButton: false, //右上角帮助按钮
        navigationInstructionsInitiallyVisibl: false,
        useDefaultRenderLoop: true,
        showRenderLoopErrors: true,
        projectionPicker: false,
        shouldAnimate: true,
        terrainProvider: worldTerrain,
    });
    mapset(viewer2);
    layset(viewer2);
    initHandler(viewer, viewer2);
}

//恒定事件(高度、点击)
function leftclick() {
    // // 叠加地形服务
    // var terrainUrls = new Array();

    // for (var i = 0; i < subdomains.length; i++){
    //     var url = tdtUrl.replace('{s}', subdomains[i]) + 'DataServer?T=elv_c&tk=' + wapworldToken;
    //     terrainUrls.push(url);
    // }

    // var provider = new Cesium.GeoTerrainProvider({
    //     urls: terrainUrls
    // });

    // viewer.terrainProvider = provider;
    //Cesium 监听相机高度变化
    viewer.camera.changed.addEventListener(function (percentage) {
        try {
            f_SetZoomEvent();
        } catch (e) {}
    });
    // viewer.scene.screenSpaceCameraController.maximumZoomDistance = 1000000; //相机高度的最大值
    viewer.scene.screenSpaceCameraController.minimumZoomDistance = 100;
    //cesium监听相机事件
    setTimeout(() => {
        viewer.scene.camera.moveEnd.addEventListener(function (e, s) {
            //计算镜头范围方法，该方法会计算当前镜头地理坐标（弧度）范围并返回west,east,north,south 4个范围参数
            // let rectangle = viewer.camera.computeViewRectangle();
            let Cartesian3 = f_GetCurCameraInfo();
            if (Cesium.Math.toDegrees(Cartesian3.pitch) < -75) {
                f_SetMapView(
                    Cartesian3.heading,
                    Cesium.Math.toRadians(-70),
                    Cartesian3.roll,
                    Cartesian3.lon,
                    Cartesian3.lat,
                    Cartesian3.height
                );
            }
            if (Cesium.Math.toDegrees(Cartesian3.pitch) > -15) {
                f_SetMapView(
                    Cartesian3.heading,
                    Cesium.Math.toRadians(-20),
                    Cartesian3.roll,
                    Cartesian3.lon,
                    Cartesian3.lat,
                    Cartesian3.height
                );
            }
        });
    }, 3000);
    let handler3D = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    //左键键操作
    handler3D.setInputAction(function (movement) {
        let pick = viewer.scene.pick(movement.position);
        if (pick) {
            console.log(pick);
            mainStore().changeGather(false);
            f_ClearEntities(1100);
            f_ClearEntities(1101, 0);
            mainStore().changeGather(false);
            EditPlot(pick);
            return;
        }
        if (mainStore().$state.gather && !mainStore().$state.punctuation.show) {
            mainStore().changePunctuation("show", true);
        }
        if (mainStore().$state.gather) {
            // 屏幕坐标和世界坐标互转
            let cartesian3 = viewer.scene.globe.pick(
                viewer.camera.getPickRay(movement.position),
                viewer.scene
            );
            // 笛卡尔空间直角坐标系转为地理坐标（弧度制）
            let cartographic = Cesium.Cartographic.fromCartesian(cartesian3);
            // console.log(cartesian3);
            // 地理坐标（弧度制）转为经纬度坐标
            let lat = Cesium.Math.toDegrees(cartographic.latitude);
            let lng = Cesium.Math.toDegrees(cartographic.longitude);
            mainStore().changePunctuation("position", [
                lng,
                lat,
                cartographic.height,
            ]);
            mainStore().changePunctuation("position3d", cartesian3);
            if (localStorage.getItem("punctuation")) {
                let embryo = JSON.parse(localStorage.getItem("punctuation"));
                f_AddIconLabel(
                    {
                        ...embryo,
                    },
                    new Date(),
                    1100
                );
            } else {
                f_AddIconLabel(1100);
            }
        }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    //右键操作
    handler3D.setInputAction(function (click) {
        if (mainStore().$state.gather) {
            f_ClearEntities(1100);
            mainStore().changeGather(false);
            mainStore().changePunctuation("show", false);
            ElMessage("已取消标点添加！");
        }
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

    //监听鼠标滚轮事件
    handler3D.setInputAction((wheelment) => {
        //从Cesium中获取当前地图瓦片等级
        let tilesToRender = viewer.scene.globe._surface._tilesToRender;
        if (Cesium.defined(tilesToRender)) {
            var strZoom = "";
            for (let i = 0; i < tilesToRender.length; i++) {
                if (i == 0) {
                    strZoom = tilesToRender[i].level;
                }
            }
            mainStore().changeLevel(strZoom);
        }

        f_SetZoomEvent();
    }, Cesium.ScreenSpaceEventType.WHEEL);
}
/**
 * 编辑标绘
 * @returns
 */
function EditPlot(pick) {
    mainStore().changeTagEntity(pick.id);
    switch (pick.id.type) {
        case 1011:
            mainStore().changePunctuation("type", "point");
            mainStore().changePunctuation("title", "编辑标点");
            mainStore().changePunctuation("show", true);
            break;
        case 1012:
            mainStore().changePunctuation("type", "polyline");
            mainStore().changePunctuation("title", "编辑标线");
            mainStore().changePunctuation("show", true);
            break;
        case 1013:
            mainStore().changePunctuation("type", "polygon");
            mainStore().changePunctuation("title", "编辑标面");
            mainStore().changePunctuation("show", true);
            break;
        case 1014:
            mainStore().changePunctuation("type", "stereoscopic");
            mainStore().changePunctuation("title", "编辑立体字");
            mainStore().changePunctuation("show", true);
            break;
    }
    mainStore().changeEditTag(true);
}
function f_SetZoomEvent() {
    if (!m_MapGridRender) return;
    var hei = f_GetCamHeight();
    if (hei > 900 * 1000 || hei < 12 * 1000) {
        if (m_GridShow) {
            objGrid.show = false;
            m_GridShow = false;
            // viewer.imageryLayers.get(3).show = false;
        }
    } else {
        if (!m_GridShow) {
            objGrid.show = true;
            // viewer.imageryLayers.get(3).show = true;
            m_GridShow = true;
        }
    }
}
function f_GetCamHeight() {
    var cameraPos = viewer.camera.position;
    // 获取当前坐标系标准
    var ellipsoid = viewer.scene.globe.ellipsoid;
    // 根据坐标系标准，将笛卡尔坐标转换为地理坐标
    var cartographic = ellipsoid.cartesianToCartographic(cameraPos);
    // 获取镜头的高度
    var height = cartographic.height;
    return height;
}

function f_ShowGridMap(isChecked) {
    if (!isChecked) {
        objGrid.show = false;
    } else {
        objGrid.show = true;
    }
    m_GridShow = !m_GridShow;
    m_MapGridRender = !m_MapGridRender;
}
function courser() {
    var myhandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    myhandler.setInputAction(function (movement) {
        var pic = viewer.scene.pick(movement.endPosition);
        if (pic) {
            viewer.enableCursorStyle = false;
            viewer._element.style.cursor = "";
            document.documentElement.style.cursor = "pointer";
        } else {
            viewer.enableCursorStyle = true;
            document.documentElement.style.cursor = "";
        }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
}
//双图对比控制同步
function initHandler(v1, v2) {
    // var _self=null;
    // console.log(95,v1, v2, 'self');
    let handler = new Cesium.ScreenSpaceEventHandler(v1.scene.canvas);
    let handler1 = new Cesium.ScreenSpaceEventHandler(v2.scene.canvas);
    if (
        handler &&
        handler.getInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE)
    ) {
        return;
    }
    handler.setInputAction(function (movement) {
        var _camerca = v1.camera;
        v2.camera.setView({
            destination: _camerca.position,
            orientation: {
                direction: _camerca._direction,
                up: _camerca.up,
                heading: _camerca.heading,
                pitch: _camerca.pitch,
                roll: _camerca.roll,
            },
        });
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    handler.setInputAction(function (movement) {
        var _camerca = v1.camera;
        v2.camera.setView({
            destination: _camerca.position,
            orientation: {
                direction: _camerca._direction,
                up: _camerca.up,
                heading: _camerca.heading,
                pitch: _camerca.pitch,
                roll: _camerca.roll,
            },
        });
    }, Cesium.ScreenSpaceEventType.WHEEL);
    handler1.setInputAction(function (movement) {
        var _camerca = v2.camera;
        v1.camera.setView({
            destination: _camerca.position,
            orientation: {
                direction: _camerca._direction,
                up: _camerca.up,
                heading: _camerca.heading,
                pitch: _camerca.pitch,
                roll: _camerca.roll,
            },
        });
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

    handler1.setInputAction(function (movement) {
        var _camerca = v2.camera;
        v1.camera.setView({
            destination: _camerca.position,
            orientation: {
                direction: _camerca._direction,
                up: _camerca.up,
                heading: _camerca.heading,
                pitch: _camerca.pitch,
                roll: _camerca.roll,
            },
        });
    }, Cesium.ScreenSpaceEventType.WHEEL);
}
function clearHandler() {
    var _self = this;
    if (_self.handler) {
        _self.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
        _self.handler.removeInputAction(Cesium.ScreenSpaceEventType.WHEEL);
    }
    if (_self.handler1) {
        _self.handler1.removeInputAction(
            Cesium.ScreenSpaceEventType.MOUSE_MOVE
        );
        _self.handler1.removeInputAction(Cesium.ScreenSpaceEventType.WHEEL);
    }
}
//地图控件控制
function mapset(v) {
    v.timeline.container.style.display = "none";
    v.cesiumWidget.creditContainer.style.display = "none";
    var stages = v.scene.postProcessStages;
    v.scene.brightness =
        v.scene.brightness ||
        stages.add(Cesium.PostProcessStageLibrary.createBrightnessStage());
    v.scene.brightness.enabled = true;
    v.scene.brightness.uniforms.brightness = Number(1.2);
    v.scene.globe.depthTestAgainsTerrain = false;
    var CesiumViewerSceneController = v.scene.screenSpaceCameraController;
    CesiumViewerSceneController.inertiaSpin = 0.95;
    CesiumViewerSceneController.inertiaTranslate = 0.95;
    CesiumViewerSceneController.inertiaZoom = 0.9;

    v.scene.postProcessStages.fxaa.enabled = true;
    var supportsImageRenderingPixelated =
        v.cesiumWidget._supportsImageRenderingPixelated;
    if (supportsImageRenderingPixelated) {
        var vtxf_dpr = window.devicePixelRatio;
        while (vtxf_dpr >= 2.0) {
            vtxf_dpr /= 2.0;
        }
        v.resolutionScale = vtxf_dpr;
    }

    v.scene.globe.baseColor = new Cesium.Color(0, 0.02, 0.23, 1.0);
    Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(
        80,
        22,
        130,
        50
    );
    v.scene.skyBox.show = true;
    //判断viewer的区别
    var containID = v._container.id;
    if (containID == "cesiumContainer") {
        //获取鼠标实时位置
        var handler = new Cesium.ScreenSpaceEventHandler(v.scene.canvas);
        handler.setInputAction(function (movement) {
            let ellipsoid = viewer.scene.globe.ellipsoid;
            let cartesian = viewer.scene.camera.pickEllipsoid(
                movement.endPosition,
                ellipsoid
            );

            if (cartesian) {
                let cartographic = ellipsoid.cartesianToCartographic(cartesian);
                try {
                    //调用窗口中显示距离的方法
                    window.ceshi({
                        lon: Cesium.Math.toDegrees(cartographic.longitude),
                        lat: Cesium.Math.toDegrees(cartographic.latitude),
                        height: Math.ceil(
                            viewer.camera.positionCartographic.height
                        ),
                    });
                } catch (ee) {}
            } else {
            }
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

        //双击获取坐标
        // handler.setInputAction(function (movement) {
        //     var geom = {};
        //     let ellipsoid = viewer.scene.globe.ellipsoid;
        //     var position = viewer.scene.camera.pickEllipsoid(movement.position, ellipsoid);
        //     if (position) {
        //         var cartographic = ellipsoid.cartesianToCartographic(position);
        //         var lon = Cesium.Math.toDegrees(cartographic.longitude);
        //         var lat = Cesium.Math.toDegrees(cartographic.latitude);
        //         var height = Math.ceil(viewer.camera.positionCartographic.height);
        //         geom.lon = lon;
        //         geom.lat = lat;
        //         geom.height = height;
        //     }
        //     window.outgeom(geom)
        // }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
    } else {
    }
}

var objGrid = null;

//监听鼠标滚轮事件
var m_GridShow = true;
var m_MapGridRender = true;
//地图底图图层控制
function layset(vv) {
    vv.imageryLayers.remove(vv.imageryLayers.get(0));
    var weixingMap = new Cesium.UrlTemplateImageryProvider({
        url: layerMapdata.satellite,
        tilingScheme: new Cesium.WebMercatorTilingScheme(),
        minimumLevel: 1,
        maximumLevel: 20,
    });
    vv.imageryLayers.addImageryProvider(weixingMap);
    var dzmap = layerMapdata.construction;
    vv.imageryLayers.addImageryProvider(
        new Cesium.UrlTemplateImageryProvider({
            url: dzmap,
            tilingScheme: new Cesium.WebMercatorTilingScheme(),
        })
    );
    viewer.imageryLayers.get(1).alpha = 0.5;
    var dzmap = layerMapdata.electron;
    vv.imageryLayers.addImageryProvider(
        new Cesium.UrlTemplateImageryProvider({
            url: dzmap,
            tilingScheme: new Cesium.WebMercatorTilingScheme(),
            defaultAlpha: 0.5,
        })
    );
    // viewer.imageryLayers.get(3).alpha = 0.1;
    vv.camera.setView({
        destination: Cesium.Cartesian3.fromDegrees(113.82, 34.03, 1600000.0),
        orientation: {
            roll: 0.0,
        },
    });
}

/**
 * 卫星地图或电子地图显隐
 * @param {number} type 图层类型1006/1007
 * @param {boolean} show 显隐
 */
function laysetShow(type, show, x) {
    let activeMap = x ? viewer2 : viewer;
    activeMap.imageryLayers.get(type - 1006).show = show;
}
function addmaplayer(e) {
    viewer.imageryLayers.remove(viewer.imageryLayers._layers[2]);
    var zmdmap = e;
    viewer.imageryLayers.addImageryProvider(
        new Cesium.UrlTemplateImageryProvider({
            url: zmdmap,
            tilingScheme: new Cesium.WebMercatorTilingScheme(),
            minimumLevel: 1,
            maximumLevel: 21,
        })
    );
}
function layseAlpha(index, show, x) {
    let activeMap = x ? viewer2 : viewer;
    if (index == 16) {
        activeMap.imageryLayers.get(3).alpha = show;
        return;
    } else if (index == 17) {
        activeMap.imageryLayers.get(4).alpha = show;
        return;
    }
    activeMap.imageryLayers.get(index).alpha = show;
}
function f_Setmap(url, n, x) {
    if (!url) {
        objGrid = viewer.imageryLayers.addImageryProvider(
            new Cesium.UrlTemplateImageryProvider({
                url: layerMapdata.grid,
                tilingScheme: new Cesium.WebMercatorTilingScheme(),
                minimumLevel: 1,
                maximumLevel: 14,
            })
        );
        objGrid.show = true;
        objGrid.alpha = 0.8;
        return;
    }
    let activeMap = viewer;
    if (x) {
        activeMap = viewer2;
    }
    if (n == "ok") {
        activeMap.imageryLayers.addImageryProvider(
            new Cesium.UrlTemplateImageryProvider({
                url: url,
                tilingScheme: new Cesium.WebMercatorTilingScheme(),
                minimumLevel: 1,
                maximumLevel: 21,
            })
        ).show = false;
        return activeMap.imageryLayers._layers.length - 1;
    } else {
        activeMap.imageryLayers.get(url).show = n;
    }
}
function GDlkmap() {
    viewer.imageryLayers.remove(viewer.imageryLayers._layers[2]);
    // var lkmap = '/api/mapabc/traffictile?v=1.0&t=1&x={x}&y={y}&z={z}&t=' + getTimeStamp();
    var lkmap =
        "https://tm.amap.com/trafficengine/mapabc/traffictile?v=1.0&t=1&x={x}&y={y}&z={z}&t=" +
        getTimeStamp();
    viewer.imageryLayers.addImageryProvider(
        new Cesium.UrlTemplateImageryProvider({
            url: lkmap,
            tilingScheme: new AmapMercatorTilingScheme(),
            minimumLevel: 1,
            maximumLevel: 20,
        })
    );
    console.log(viewer.imageryLayers._layers);
}
//获取时间戳
function getTimeStamp() {
    let nowDate = new Date();
    let year = nowDate.getFullYear();
    let month = nowDate.getMonth() + 1;
    let today = nowDate.getDate();
    let hours = nowDate.getHours();
    let min = nowDate.getMinutes();
    let seconds = nowDate.getSeconds();
    if (month >= 1 && month <= 9) {
        month = "0" + month;
    }
    if (today >= 1 && today <= 9) {
        today = "0" + today;
    }
    if (seconds >= 1 && seconds <= 9) {
        seconds = "0" + seconds;
    }
    let currentdate =
        year +
        "-" +
        month +
        "-" +
        today +
        " " +
        hours +
        ":" +
        min +
        ":" +
        seconds;
    let longTime = new Date(
        currentdate.replace(new RegExp("-", "gm"), "/")
    ).getTime();
    console.log(longTime, currentdate);
    return longTime;
}
//墨卡托坐标初始化为经纬度坐标之后定位
function flyto(wkt, n) {
    wkt = wkt.replaceAll("POINT(", "");
    wkt = wkt.replaceAll(")", "");
    let xy = wkt.split(" ");
    let lng = (parseFloat(xy[0]) / 20037508.34) * 180;
    let lat = (parseFloat(xy[1]) / 20037508.34) * 180;
    lat =
        (180 / Math.PI) *
        (2 * Math.atan(Math.exp((lat * Math.PI) / 180)) - Math.PI / 2);
    if (!n) {
        Zoomto(lng, lat, 1000.0);
    } else {
        return [lng, lat];
    }
}
//经纬度坐标定位
async function Zoomto(x, y, h) {
    // console.log(6166, x, y, h);
    if (h) {
        return await viewer.camera.flyTo({
            destination: Cesium.Cartesian3.fromDegrees(x, y, h),
        });
    }
    if (y == 1) {
        return await viewer.flyTo(x);
    } else {
        await viewer.camera.flyTo({
            destination: new Cesium.Cartesian3(
                x.x - 830,
                x.y + 2000,
                x.z + 320
            ),
            orientation: {
                // 指向
                heading: 8.881784197001252e-16,
                // 视角
                pitch: -1.0707963267948966,
                roll: 0,
            },
        });
        if (y) {
            setTimeout(() => {
                for (var i = viewer.entities.values.length - 1; i >= 0; i--) {
                    if (
                        viewer.entities.values[i].type == 1011 &&
                        Number(viewer.entities.values[i].code) == y.id
                    ) {
                        console.log(123645);
                        viewer.flyTo(viewer.entities.values[i]);
                    }
                }
            }, 3000);
        }
    }
}
/**
 * 加载3DTile
 * @param {string} url
 * @param {number} height
 */
function f_LoadTile(url, height) {
    var tileset = new Cesium.Cesium3DTileset({
        url: url,
    });
    // console.log(348, tileset.readyPromise);
    viewer.zoomTo(tileset);
    viewer.scene.primitives.add(tileset);
    tileset.readyPromise.then(function (argument) {
        var cartographic = Cesium.Cartographic.fromCartesian(
            tileset.boundingSphere.center
        );
        var surface = Cesium.Cartesian3.fromRadians(
            cartographic.longitude,
            cartographic.latitude,
            cartographic.height
        );
        var offset = Cesium.Cartesian3.fromRadians(
            cartographic.longitude,
            cartographic.latitude,
            cartographic.height + height
        );
        var translation = Cesium.Cartesian3.subtract(
            offset,
            surface,
            new Cesium.Cartesian3()
        );
        tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation);
    });
    return tileset;
}
function remove3Dtile() {
    console.log(viewer.scene.primitives._primitives);
    for (
        let index = viewer.scene.primitives._primitives.length - 1;
        index >= 1;
        index--
    ) {
        viewer.scene.primitives.remove(
            viewer.scene.primitives._primitives[index]
        );
    }
}
/**
 * 加载虚幻导出模型
 * @param {string} url
 * @param {number} height
 */
function f_UELoadTile(url, height) {
    var tileset = new Cesium.Cesium3DTileset({
        url: url,
    });
    viewer.scene.primitives.add(tileset);
    viewer.zoomTo(tileset);
    tileset.readyPromise.then(function (argument) {
        tileSetAll(tileset, 113.8236212, 34.8434313, -75, 0, 0, 0, 1);
    });
    return tileset;
}
//处理模型
function tileSetAll(
    tileset,
    longitude,
    latitude,
    height,
    rotateX,
    rotateY,
    rotateZ,
    scale
) {
    //旋转角度设置
    var mx = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(rotateX));
    var my = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(rotateY));
    var mz = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(rotateZ));
    var rotationX = Cesium.Matrix4.fromRotationTranslation(mx);
    var rotationY = Cesium.Matrix4.fromRotationTranslation(my);
    var rotationZ = Cesium.Matrix4.fromRotationTranslation(mz);
    //平移 修改经纬度
    var position = Cesium.Cartesian3.fromDegrees(longitude, latitude, height);
    var transform = Cesium.Transforms.eastNorthUpToFixedFrame(position);
    //旋转、平移矩阵相乘
    Cesium.Matrix4.multiply(transform, rotationX, transform);
    Cesium.Matrix4.multiply(transform, rotationY, transform);
    Cesium.Matrix4.multiply(transform, rotationZ, transform);
    //缩放 修改缩放比例
    var scale1 = Cesium.Matrix4.fromUniformScale(scale);
    Cesium.Matrix4.multiply(transform, scale1, transform);
    //赋值给tileset
    tileset._root.transform = transform;
}
/**
 * 添加实体标注
 * @param {Array<number>} data
 */
async function f_AddPoi(data, i) {
    f_ClearEntities(1100);
    if (i) {
        await Zoomto(JSON.parse(data.position), data);
    } else {
        let POI = viewer.entities.add({
            position: Cesium.Cartesian3.fromDegrees(
                Number(data.displayX),
                Number(data.displayY),
                1000.0
            ),
            type: 1100,
            label: {
                text: data.name,
                font: "14pt monospace",
                style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                outlineWidth: 2,
                pixelOffset: new Cesium.Cartesian2(0, 0),
                verticalOrigin: Cesium.VerticalOrigin.TOP,
            },
        });
        viewer.flyTo(POI);
    }
}
function cehis() {
    let embryo = viewer.entities.add({
        position: Cesium.Cartesian3.fromDegrees(113.051974, 34.389828, 100),
        type: 8888,
        label: {
            text: "测试",
            font: "14pt monospace",
            style: Cesium.LabelStyle.FILL_AND_OUTLINE,
            outlineWidth: 2,
            verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, //贴地
            pixelOffset: new Cesium.Cartesian2(0, -37),
        },
        billboard: {
            image: "http://www.yugaosu.com:18081/zlgs/image/image-16911415665310563.png",
            width: 29,
            height: 37,
            verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, //贴地
            distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
                0,
                2000000
            ), //当缩放到一定程度时隐藏该实体,不设置则一直显示
        },
    });
    viewer.flyTo(embryo);
}
/**
 * 清除实体
 */
function f_ClearEntities(type, code) {
    if (type) {
        for (var i = viewer.entities.values.length - 1; i >= 0; i--) {
            if (code) {
                if (
                    viewer.entities.values[i].type == type &&
                    Number(viewer.entities.values[i].code) == code
                ) {
                    viewer.entities.remove(viewer.entities.values[i]);
                }
            } else {
                if (viewer.entities.values[i].type == type) {
                    viewer.entities.remove(viewer.entities.values[i]);
                }
            }
        }
        if (code == 0 && braid) {
            braid.destroy(); //关闭事件句柄
            braid = null;
        }
    } else {
        for (var i = viewer.entities.values.length - 1; i >= 0; i--) {
            if (!viewer.entities.values[i].type) {
                viewer.entities.remove(viewer.entities.values[i]);
            }
        }
    }
}
window.f_ClearEntities = f_ClearEntities;
/**
 * 自定义require
 * @param {string} name 文件名
 */
function myrequire(name) {
    return new URL(`../assets/icon/${name}.png`, import.meta.url).href;
}
/**
 * rgba颜色转换
 */
function colorConvert(Color) {
    let text = Color.substring(5);
    let borderColorString = text.substring(0, text.length - 1);
    let borderColor = borderColorString.split(",");
    return new Cesium.Color(
        Number(borderColor[0]) / 255,
        Number(borderColor[1]) / 255,
        Number(borderColor[2]) / 255,
        Number(borderColor[3])
    );
}
/**
 * 添加图标和文字
 * @param {string} name 标注名称
 * @param {number} code 标识
 * @param {Array<number>} xy 坐标
 */

function f_AddIconLabel(embryo, code, type) {
    f_ClearEntities(1100);
    let Cartesian3 = mainStore().$state.punctuation.position3d,
        style = Cesium.LabelStyle.FILL,
        x = 0,
        y = -39,
        outlineColor = new Cesium.Color(1, 0, 0, 1.0),
        fillColor = new Cesium.Color(1, 0, 0, 1.0),
        hrefimg = null;
    if (embryo != 1100 && embryo.position)
        Cartesian3 = JSON.parse(embryo.position);
    if (embryo != 1100) {
        if (embryo.borderSize != 0) {
            style = Cesium.LabelStyle.FILL_AND_OUTLINE;
            outlineColor = colorConvert(embryo.borderColor);
        }
        if (embryo.surround != 1) {
            let leshd =
                embryo.name.length * embryo.fontSize > 30
                    ? embryo.name.length * embryo.fontSize + 2
                    : 34;
            if (embryo.surround == 0) x = -leshd;
            if (embryo.surround == 2) x = leshd;
            y = embryo.fontSize > 37 ? -(embryo.fontSize / 2) : -10;
        }
        fillColor = colorConvert(embryo.fontColor);
        if (embryo.iconImg.includes(".png")) {
            hrefimg = "http://www.yugaosu.com:18081/zlgs/" + embryo.iconImg;
        }
    }
    return viewer.entities.add({
        name: embryo == 1100 ? "" : embryo.name,
        code: code,
        type: embryo == 1100 ? embryo : type,
        embryo,
        position: new Cesium.Cartesian3(
            Cartesian3.x,
            Cartesian3.y,
            Cartesian3.z
        ),
        label: {
            text: embryo == 1100 ? "" : embryo.name,
            font: `${embryo == 1100 ? 14 : embryo.fontSize}pt yahei`,
            style: style,
            verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            pixelOffset: new Cesium.Cartesian2(x, y),
            fillColor: fillColor,
            outlineWidth: embryo == 1100 ? 1 : embryo.borderSize,
            outlineColor: outlineColor,
            heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, //贴地
            distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
                0,
                embryo == 1100 ? 2000000 : embryo.SightDistance
            ), //当缩放到一定程度时隐藏该实体,不设置则一直显示
        },
        billboard: {
            image:
                hrefimg || myrequire(embryo == 1100 ? "addpt" : embryo.iconImg),
            width: 29,
            height: 37,
            verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, //贴地
            distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
                0,
                embryo == 1100 ? 2000000 : embryo.SightDistance
            ), //当缩放到一定程度时隐藏该实体,不设置则一直显示
        },
    });
}

/**
 * 自定义添加图标和文字
 * @param {string} name 标注名称
 * @param {number} code 标识
 * @param {number} type 类型
 * @param {Array<number>} xy 坐标
 * @param {number} fontSize 文字大小
 * @param {string} color 文字颜色
 * @param {number} groundClearance 显示高度
 * @param {string} url 图标名称
 * @param {number} width 图标宽度
 * @param {number} height 图标高度
 */
function f_AddDimension(
    name,
    code,
    type,
    xy,
    fontSize,
    color,
    groundClearance,
    url,
    width,
    height
) {
    viewer.entities.add({
        name: name,
        code: code,
        type: type,
        position: Cesium.Cartesian3.fromDegrees(xy[0], xy[1], 10),
        label: {
            text: type != 1003 ? name : "",
            font: `${fontSize}pt yahei`,
            style: Cesium.LabelStyle.FILL_AND_OUTLINE, // FILL_AND_OUTLINE填充和轮廓
            verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            pixelOffset: new Cesium.Cartesian2(0, -16),
            fillColor: new Cesium.Color.fromCssColorString(color),
            outlineWidth: 1,
            outlineColor: Cesium.Color.WHEAT,
            distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
                0,
                groundClearance
            ), //当缩放到一定程度时隐藏该实体,不设置则一直显示
        },
        billboard: {
            image:
                type != 1003
                    ? new URL(`../assets/icon/${url}.png`, import.meta.url).href
                    : new URL(`../assets/gsname/${url}.png`, import.meta.url)
                          .href,
            width: width,
            height: height,
            distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
                0,
                groundClearance
            ), //当缩放到一定程度时隐藏该实体,不设置则一直显示
        },
    });
}

/**
 * 收费站或服务区显隐
 * @param {number} type 图标类型1004/1005
 * @param {boolean} show 显隐
 */
function entitiesShow(type, show) {
    console.log(viewer.dataSources);
    viewer.dataSources._dataSources.forEach((elsiem) => {
        if (elsiem.type == type) {
            elsiem.entities.values.forEach((element) => {
                element._show = show;
            });
        }
    });
}
/**
 * 添加实体线
 * @param {array<number>} geom 坐标数组
 */
function f_AddPolyLine(geom) {
    f_ClearEntities();
    console.log(Cesium.Cartesian3.fromDegreesArray(geom));
    var obj = viewer.entities.add({
        // name:'myline',
        polyline: {
            positions: Cesium.Cartesian3.fromDegreesArray(geom),
            width: 5,
            material: Cesium.Color.RED,
            clampToGround: true,
        },
    });
    viewer.zoomTo(obj);
}
/**
 * 自定义添加实体线
 * @param {string} name 线名称
 * @param {number} code 标识
 * @param {number} type 类型
 * @param {array<number>} geom 坐标数组
 * @param {number} width 宽度
 * @param {string} color 颜色
 */
function f_AddPolyCustom(name, code, type, geom, width, color) {
    f_ClearEntities();
    var obj = viewer.entities.add({
        name: name,
        code: code,
        type: type,
        polyline: {
            positions: Cesium.Cartesian3.fromDegreesArray(geom),
            width: width,
            material: new Cesium.Color.fromCssColorString(color),
            clampToGround: true,
        },
    });
    viewer.zoomTo(obj);
}
function f_LoadJson(url_json) {
    var geojsonOptions = {
        clampToGround: true, //使数据贴地
    };
    var promise = Cesium.GeoJsonDataSource.load(url_json, geojsonOptions);
    return promise;
}
function f_Township() {
    let obj_gd = f_LoadJson("./data/84zlgsg.json");
    setTimeout(async () => {
        if (obj_gd != null) {
            await obj_gd
                .then(function (dataSource) {
                    viewer.dataSources.add(dataSource);
                    let entities = dataSource.entities.values;
                    for (let i = 0; i < entities.length; i++) {
                        let entity = entities[i];
                        entity.polyline.width = 5;
                        if (entity.properties.gid == 1) {
                            entity.polyline.material =
                                new Cesium.Color.fromCssColorString("#4fb043");
                            entity.type = 3;
                            entity.name = "TJ-3标";
                        }
                        if (entity.properties.gid == 2) {
                            entity.polyline.material =
                                new Cesium.Color.fromCssColorString("#ff1e10");
                            entity.type = 4;
                            entity.name = "TJ-4标";
                        }
                        if (entity.properties.gid == 3) {
                            entity.polyline.material =
                                new Cesium.Color.fromCssColorString("#1d99f8");
                            entity.type = 1;
                            entity.name = "TJ-1标";
                        }
                        if (entity.properties.gid == 4) {
                            entity.polyline.material =
                                new Cesium.Color.fromCssColorString("#ffbe00");
                            entity.type = 2;
                            entity.name = "TJ-2标";
                        }
                        mainStore().changeTenders(entity);
                    }
                })
                .otherwise(function (error) {
                    console.log(error);
                });
        }
    }, 0);
}
function fwqIconAdd(
    dataUrl,
    type,
    fontSize,
    color,
    url,
    groundClearance,
    width,
    height
) {
    let obj_gd = f_LoadJson(`./data/${dataUrl}.json`);
    setTimeout(async () => {
        if (obj_gd != null) {
            await obj_gd
                .then(function (dataSource) {
                    dataSource.type = type;
                    viewer.dataSources.add(dataSource);
                    let entities = dataSource.entities.values;
                    for (let i = 0; i < entities.length; i++) {
                        let entity = entities[i];
                        entity.billboard = null;
                        entity.label = null;
                        entity.code =
                            type == 1001
                                ? Number(entity.properties.zh._value)
                                : i;
                        entity.type = type;
                        let name = null;
                        let pixelOffset = new Cesium.Cartesian2(1, -36);
                        let verticalOrigin = Cesium.VerticalOrigin.BOTTOM;
                        if (type == 1001) {
                            let gzlname = entity.properties.zh._value;
                            name = "K" + gzlname;
                            pixelOffset = new Cesium.Cartesian2(1, -30);
                        } else {
                            name = entity.name;
                        }
                        if (type == 1004) {
                            verticalOrigin = Cesium.VerticalOrigin.LEFT;
                            pixelOffset = new Cesium.Cartesian2(
                                16 + name.length * 7,
                                -46
                            );
                        }
                        if (type == 1005)
                            pixelOffset = new Cesium.Cartesian2(1, -66);
                        if (type == 1006 && entity.properties.type._value == 1)
                            url = "icolj";
                        if (type == 1006 && entity.properties.type._value == 2)
                            url = "ico_qn";
                        entity.label = {
                            text: name,
                            font: `${fontSize}pt yahei`,
                            style: Cesium.LabelStyle.FILL,
                            verticalOrigin: verticalOrigin,
                            pixelOffset: pixelOffset,
                            heightReference:
                                Cesium.HeightReference.CLAMP_TO_GROUND,
                            disableDepthTestDistance: Number.POSITIVE_INFINITY,
                            fillColor: new Cesium.Color.fromCssColorString(
                                color
                            ),
                            distanceDisplayCondition:
                                new Cesium.DistanceDisplayCondition(
                                    0,
                                    type == 1001 &&
                                    Number(entity.properties.zh._value) % 5 == 0
                                        ? groundClearance * 4
                                        : groundClearance
                                ), //当缩放到一定程度时隐藏该实体,不设置则一直显示
                            showBackground: type == 1004 ? true : false, //是否显示背景颜色
                            backgroundColor:
                                new Cesium.Color.fromCssColorString(
                                    "#000000b3"
                                ), //背景颜色
                        };

                        entity.billboard = {
                            image: new URL(
                                `../assets/icon/${url}.png`,
                                import.meta.url
                            ).href,
                            pixelOffset: new Cesium.Cartesian2(
                                0,
                                type == 1004 || type == 1005 ? -46 : -16
                            ),
                            width,
                            height,
                            heightReference:
                                Cesium.HeightReference.CLAMP_TO_GROUND + 1, //贴地
                            distanceDisplayCondition:
                                new Cesium.DistanceDisplayCondition(
                                    0,
                                    type == 1001 &&
                                    Number(entity.properties.zh._value) % 5 == 0
                                        ? groundClearance * 4
                                        : groundClearance
                                ), //当缩放到一定程度时隐藏该实体,不设置则一直显示
                        };
                    }
                    if (type == 1001) {
                        let transfer = entities;
                        transfer.sort(sortBy("code", -1));
                        function sortBy(attr, rev) {
                            if (rev == undefined) {
                                rev = 1;
                            } else {
                                rev ? 1 : -1;
                            }
                            return function (a, b) {
                                a = a[attr];
                                b = b[attr];
                                if (a < b) {
                                    return rev * -1;
                                }
                                if (a > b) {
                                    return rev * 1;
                                }
                                return 0;
                            };
                        }
                        mainStore().changeGlzArrys(transfer);
                    } else if (type == 1004)
                        mainStore().$state.sfzArrys = entities;
                    else if (type == 1005)
                        mainStore().$state.fwqArrys = entities;
                    else if (type == 1006)
                        mainStore().$state.ljArrys = entities;
                })
                .otherwise(function (error) {
                    console.log(error);
                });
        }
    }, 0);
}
/**
 * 添加管线
 * @param {array<number>} geom 坐标数组
 */
function f_AddpolylineVolume(pos) {
    f_ClearEntities();
    var obj = viewer.entities.add({
        polylineVolume: {
            positions: Cesium.Cartesian3.fromDegreesArray(pos),
            shape: computeCircle(10),
            height: 0,
            material: Cesium.Color.GREEN.withAlpha(0.5),
        },
    });
    viewer.zoomTo(obj);
}

function computeCircle(radius) {
    let positions = [];
    for (let i = 0; i < 360; i++) {
        let radis = Cesium.Math.toRadians(i);
        positions.push(
            new Cesium.Cartesian2(
                radius * Math.cos(radis),
                radius * Math.sin(radis)
            )
        );
    }
    return positions;
}

/**
 * 添加面
 * @param {Array<number>} reg 面坐标
 */
function f_AddReg(reg) {
    f_ClearEntities();
    var stripeMaterial = new Cesium.StripeMaterialProperty({
        evenColor: Cesium.Color.WHITE.withAlpha(0.5),
        oddColor: Cesium.Color.BLUE.withAlpha(0.5),
        repeat: 5.0,
    });
    // var entities = viewer.entities;
    var obj = viewer.entities.add({
        polygon: {
            hierarchy: new Cesium.PolygonHierarchy(
                Cesium.Cartesian3.fromDegreesArray(reg)
            ),
            outline: true,
            outlineColor: Cesium.Color.WHITE,
            outlineWidth: 4,
            material: stripeMaterial,
        },
    });
    viewer.zoomTo(obj);
}
/**测量距离 */
function measureLine() {
    // f_ClearEntities();
    viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
        Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
    );
    var m_cl_handler = new Cesium.ScreenSpaceEventHandler(
        viewer.scene._imageryLayerCollection
    );
    var positions = [];
    var poly = null;
    var distance = 0;
    var cartesian = null;
    var floatingPoint;
    var labelPt = null;
    m_cl_handler.setInputAction(function (movement) {
        let ray = viewer.camera.getPickRay(movement.endPosition);
        cartesian = viewer.scene.globe.pick(ray, viewer.scene);
        if (!Cesium.defined(cartesian))
            //跳出地球时异常
            return;
        if (positions.length >= 2) {
            if (!Cesium.defined(poly)) {
                poly = new PolyLinePrimitive(positions);
            } else {
                positions.pop();
                positions.push(cartesian);
            }
        }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

    m_cl_handler.setInputAction(function (movement) {
        let ray = viewer.camera.getPickRay(movement.position);
        cartesian = viewer.scene.globe.pick(ray, viewer.scene);
        if (!Cesium.defined(cartesian))
            //跳出地球时异常
            return;
        if (positions.length == 0) {
            positions.push(cartesian.clone());
        }
        positions.push(cartesian);
        //记录鼠标单击时的节点位置，异步计算贴地距离
        labelPt = positions[positions.length - 1];
        if (positions.length > 2) {
            getSpaceDistance(positions);
        } else if (positions.length == 2) {
            //在三维场景中添加Label
            //不能添加到viewer里面，不好清除掉
            floatingPoint = viewer.entities.add({
                name: "空间距离",
                position: labelPt,
                point: {
                    pixelSize: 5,
                    color: Cesium.Color.RED,
                    outlineColor: Cesium.Color.WHITE,
                    outlineWidth: 2,
                },
            });
        }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

    m_cl_handler.setInputAction(function (movement) {
        m_cl_handler.destroy(); //关闭事件句柄
        m_cl_handler = undefined;
        positions.pop(); //最后一个点无效
        if (positions.length == 1) viewer.entities.remove(floatingPoint);
    }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);

    var PolyLinePrimitive = (function () {
        class _ {
            constructor(positions) {
                this.options = {
                    name: "直线",
                    polyline: {
                        show: true,
                        positions: [],
                        material: Cesium.Color.CHARTREUSE,
                        width: 3,
                        clampToGround: true,
                    },
                };
                this.positions = positions;
                this._init();
            }
            _init() {
                var _self = this;
                var _update = function () {
                    return _self.positions;
                };
                //实时更新polyline.positions
                this.options.polyline.positions = new Cesium.CallbackProperty(
                    _update,
                    false
                );
                viewer.entities.add(this.options);
            }
        }

        return _;
    })();

    //空间两点距离计算函数
    function getSpaceDistance(positions) {
        //只计算最后一截，与前面累加
        //因move和鼠标左击事件，最后两个点坐标重复
        var i = positions.length - 3;
        var point1cartographic = Cesium.Cartographic.fromCartesian(
            positions[i]
        );
        var point2cartographic = Cesium.Cartographic.fromCartesian(
            positions[i + 1]
        );
        getTerrainDistance(point1cartographic, point2cartographic);
    }

    function getTerrainDistance(point1cartographic, point2cartographic) {
        var geodesic = new Cesium.EllipsoidGeodesic();
        geodesic.setEndPoints(point1cartographic, point2cartographic);
        var s = geodesic.surfaceDistance;
        var cartoPts = [point1cartographic];
        for (var jj = 1000; jj < s; jj += 1000) {
            //分段采样计算距离
            var cartoPt = geodesic.interpolateUsingSurfaceDistance(jj);
            cartoPts.push(cartoPt);
        }
        cartoPts.push(point2cartographic);
        //返回两点之间的距离
        Cesium.sampleTerrain(viewer.terrainProvider, 8, cartoPts).then(
            (updatedPositions) => {
                for (var jj = 0; jj < updatedPositions.length - 1; jj++) {
                    var geoD = new Cesium.EllipsoidGeodesic();
                    geoD.setEndPoints(
                        updatedPositions[jj],
                        updatedPositions[jj + 1]
                    );
                    var innerS = geoD.surfaceDistance;
                    innerS = Math.sqrt(
                        Math.pow(innerS, 2) +
                            Math.pow(
                                updatedPositions[jj + 1].height -
                                    updatedPositions[jj].height,
                                2
                            )
                    );
                    distance += innerS;
                }
                //在三维场景中添加Label
                var lon1 =
                    viewer.scene.globe.ellipsoid.cartesianToCartographic(
                        labelPt
                    ).longitude;
                var lat1 =
                    viewer.scene.globe.ellipsoid.cartesianToCartographic(
                        labelPt
                    ).latitude;
                var lonLat =
                    "(" +
                    Cesium.Math.toDegrees(lon1).toFixed(2) +
                    "," +
                    Cesium.Math.toDegrees(lat1).toFixed(2) +
                    ")";
                var textDisance = distance.toFixed(2) + "米";
                if (distance > 10000)
                    textDisance = (distance / 1000.0).toFixed(2) + "千米";
                floatingPoint = viewer.entities.add({
                    name: "贴地距离",
                    position: labelPt,
                    point: {
                        pixelSize: 5,
                        color: Cesium.Color.RED,
                        outlineColor: Cesium.Color.WHITE,
                        outlineWidth: 2,
                    },
                    label: {
                        text: textDisance,
                        font: "18px sans-serif",
                        fillColor: Cesium.Color.GOLD,
                        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                        outlineWidth: 2,
                        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                        pixelOffset: new Cesium.Cartesian2(20, -20),
                    },
                });
            }
        );
    }
}
/**测量面积 */
function mesurePolygon() {
    var m_cl_handler = new Cesium.ScreenSpaceEventHandler(
        viewer.scene._imageryLayerCollection
    );
    var positions = [];
    var tempPoints = [];
    var polygon = null;
    var gonfloating;
    var cartesian = null;
    m_cl_handler.setInputAction(function (movement) {
        let ray = viewer.camera.getPickRay(movement.endPosition);
        cartesian = viewer.scene.globe.pick(ray, viewer.scene);
        positions.pop(); //移除最后一个
        positions.push(cartesian);
        if (positions.length >= 2) {
            var dynamicPositions = new Cesium.CallbackProperty(function () {
                return new Cesium.PolygonHierarchy(positions);
                return positions;
            }, false);
            polygon = PolygonPrimitive(dynamicPositions);
        }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

    m_cl_handler.setInputAction(function (movement) {
        let ray = viewer.camera.getPickRay(movement.position);
        cartesian = viewer.scene.globe.pick(ray, viewer.scene);
        if (positions.length == 0) {
            positions.push(cartesian.clone());
        }
        positions.push(cartesian);
        //在三维场景中添加点
        var cartographic = Cesium.Cartographic.fromCartesian(
            positions[positions.length - 1]
        );
        var longitudeString = Cesium.Math.toDegrees(cartographic.longitude);
        var latitudeString = Cesium.Math.toDegrees(cartographic.latitude);
        var heightString = cartographic.height;
        var labelText =
            "(" +
            longitudeString.toFixed(2) +
            "," +
            latitudeString.toFixed(2) +
            ")";
        tempPoints.push({
            lon: longitudeString,
            lat: latitudeString,
            hei: heightString,
        });
        gonfloating = viewer.entities.add({
            name: "多边形面积",
            position: positions[positions.length - 1],
            point: {
                pixelSize: 5,
                color: Cesium.Color.RED,
                outlineColor: Cesium.Color.WHITE,
                outlineWidth: 2,
                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
            },
            label: {
                font: "18px sans-serif",
                fillColor: Cesium.Color.GOLD,
                style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                outlineWidth: 2,
                verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                pixelOffset: new Cesium.Cartesian2(20, -20),
            },
        });
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

    m_cl_handler.setInputAction(function (movement) {
        m_cl_handler.destroy();
        positions.pop();
        var textArea = getArea(tempPoints) + "平方公里";
        viewer.entities.add({
            name: "多边形面积",
            position: positions[positions.length - 1],
            label: {
                text: textArea,
                font: "18px sans-serif",
                fillColor: Cesium.Color.GOLD,
                style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                outlineWidth: 2,
                verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                pixelOffset: new Cesium.Cartesian2(20, -40),
                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
            },
        });
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
    var radiansPerDegree = Math.PI / 180;
    var degreesPerRadian = 180.0 / Math.PI; //弧度转化为角度
    function getArea(points) {
        var res = 0;
        for (let i = 0; i < points.length - 2; i++) {
            let j = (i + 1) % points.length;
            let k = (i + 2) % points.length;
            var totalAngle = Angle(points[i], points[j], points[k]);
            var dis_temp1 = distance(positions[i], positions[j]);
            var dis_temp2 = distance(positions[j], positions[k]);
            res += dis_temp1 * dis_temp2 * Math.abs(Math.sin(totalAngle));
        }
        return (res / 1000000.0).toFixed(4);
    }
    function Angle(p1, p2, p3) {
        var bearing21 = Bearing(p2, p1);
        var bearing23 = Bearing(p2, p3);
        var angle = bearing21 - bearing23;
        if (angle < 0) {
            angle += 360;
        }
        return angle;
    }
    function Bearing(from, to) {
        var lat1 = from.lat * radiansPerDegree;
        var lon1 = from.lon * radiansPerDegree;
        var lat2 = to.lat * radiansPerDegree;
        var lon2 = to.lon * radiansPerDegree;
        var angle = -Math.atan2(
            Math.sin(lon1 - lon2) * Math.cos(lat2),
            Math.cos(lat1) * Math.sin(lat2) -
                Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon1 - lon2)
        );
        if (angle < 0) {
            angle += Math.PI * 2.0;
        }
        angle = angle * degreesPerRadian; //角度
        return angle;
    }

    function PolygonPrimitive(positions) {
        polygon = viewer.entities.add({
            polygon: {
                hierarchy: positions,
                material: Cesium.Color.GREEN.withAlpha(0.1),
            },
        });
    }

    function distance(point1, point2) {
        var point1cartographic = Cesium.Cartographic.fromCartesian(point1);
        var point2cartographic = Cesium.Cartographic.fromCartesian(point2);
        /**根据经纬度计算出距离**/
        var geodesic = new Cesium.EllipsoidGeodesic();
        geodesic.setEndPoints(point1cartographic, point2cartographic);
        var s = geodesic.surfaceDistance;
        //返回两点之间的距离
        s = Math.sqrt(
            Math.pow(s, 2) +
                Math.pow(
                    point2cartographic.height - point1cartographic.height,
                    2
                )
        );
        return s;
    }
}
/**添加墙体 */
function f_creatwall(type) {
    f_ClearEntities();
    let redwall = viewer.entities.add({
        name: "红墙",
        wall: {
            positions: Cesium.Cartesian3.fromDegreesArrayHeights(
                //坐标第三个参数是高度,应用带高度的坐标时cesiumAPI也要有height字段,否则报错
                [-115.0, 44.0, 200000.0, -90.0, 44.0, 200000.0]
            ),
            minimumHeights: [100000.0, 100000.0], //坐标点的最小高度数组
            material: Cesium.Color.RED.withAlpha(0.5),
        },
    });
    let greenwall = viewer.entities.add({
        name: "绿围墙",
        wall: {
            positions: Cesium.Cartesian3.fromDegreesArrayHeights([
                -107.0, 43.0, 100000.0, -97.0, 43.0, 100000.0, -97.0, 40.0,
                100000.0, -107.0, 40.0, 100000.0, -107.0, 43.0, 100000.0,
            ]),
            outline: true, //外边线
            outlineColor: Cesium.Color.BLACK, //外边线颜色
            material: Cesium.Color.GREEN.withAlpha(0.5),
        },
    });
    let bluewall = viewer.entities.add({
        name: "蓝墙数组不含高",
        wall: {
            position: Cesium.Cartesian3.fromDegreesArray([
                -115.0, 50.0, -112.5, 50.0, -110.0, 50.0, -107.5, 50.0, -105.0,
                50.0, -102.5, 50.0, -100.0, 50.0, -97.5, 50.0, -95.0, 50.0,
                -92.5, 50.0, -90.0, 50.0,
            ]),
            maximumHeights: [
                100000, 200000, 100000, 200000, 100000, 200000, 100000, 200000,
                100000, 200000, 100000,
            ],
            minimumHeights: [
                0, 100000, 0, 100000, 0, 100000, 0, 100000, 0, 100000, 0,
            ],
            material: Cesium.Color.BLUE.withAlpha(0.5),
            outline: true,
            outlineColor: Cesium.Color.BLACK,
        },
    });
    if (type == "redwall") {
        viewer.zoomTo(redwall);
    } else if (type == "greenwall") {
        viewer.zoomTo(greenwall);
    } else {
        viewer.zoomTo(bluewall);
    }
}
/**切换显示模式 */
function f_ShowMapModel(type) {
    if (type == 0) {
        //3d模式
        viewer.scene.morphTo3D(1);
    } else if (type == 1) {
        // 2D 模式
        viewer.scene.morphTo2D(1);
    } else {
        // 2.5D 哥伦布模式
        viewer.scene.morphToColumbusView(1);
    }
}
/**走廊 */
function f_AddZL() {
    var redCorridor = viewer.entities.add({
        name: "Red corridor on surface with rounded corners and outline",
        corridor: {
            positions: Cesium.Cartesian3.fromDegreesArray([
                -100.0, 40.0, -105.0, 40.0, -105.0, 35.0,
            ]),
            width: 200000.0,
            material: Cesium.Color.RED.withAlpha(0.5),
            outline: true,
            outlineColor: Cesium.Color.RED,
        },
    });

    var greenCorridor = viewer.entities.add({
        name: "Green corridor at height with mitered corners",
        corridor: {
            positions: Cesium.Cartesian3.fromDegreesArray([
                -90.0, 40.0, -95.0, 40.0, -95.0, 35.0,
            ]),
            height: 100000.0,
            width: 200000.0,
            cornerType: Cesium.CornerType.MITERED,
            material: Cesium.Color.GREEN,
        },
    });

    var blueCorridor = viewer.entities.add({
        name: "Blue extruded corridor with beveled corners and outline",
        corridor: {
            positions: Cesium.Cartesian3.fromDegreesArray([
                115.094744035, 34.994646376, 115.08659113, 34.990193891,
                115.076629904, 34.986538555, 115.066144992, 34.983975398,
                115.055940538, 34.980727417, 115.046577852, 34.976081298,
                115.038208335, 34.970280845, 115.029406294, 34.964968225,
                115.019725463, 34.960808907, 115.009388951, 34.95786287,
                114.999220044, 34.954514251, 114.989671079, 34.950093647,
                114.980099682, 34.945774868, 114.969782147, 34.942813504,
                114.959012817, 34.941282007, 114.948145285, 34.940137071,
            ]),
            height: 10.0,
            extrudedHeight: 2.0,
            width: 10,
            cornerType: Cesium.CornerType.ROUNDED,
            material: Cesium.Color.GREEN.withAlpha(0.5),
            outline: false,
            outlineColor: Cesium.Color.GREEN,
        },
    });
    // return blueCorridor;
    viewer.zoomTo(blueCorridor);
}
/**球体 */
function f_AddBall() {
    var blueEllipsoid = viewer.entities.add({
        name: "Blue ellipsoid",
        position: Cesium.Cartesian3.fromDegrees(-114.0, 40.0, 300000.0),
        ellipsoid: {
            //可以指定三个轴的半径
            radii: new Cesium.Cartesian3(200000.0, 200000.0, 300000.0),
            material: Cesium.Color.BLUE,
        },
    });

    var redSphere = viewer.entities.add({
        name: "Red sphere with black outline",
        position: Cesium.Cartesian3.fromDegrees(-107.0, 40.0, 300000.0),
        ellipsoid: {
            //正球体
            radii: new Cesium.Cartesian3(300000.0, 300000.0, 300000.0),
            material: Cesium.Color.RED,
            outline: true,
            outlineColor: Cesium.Color.BLACK,
        },
    });

    var outlineOnly = viewer.entities.add({
        name: "Yellow ellipsoid outline",
        position: Cesium.Cartesian3.fromDegrees(-100.0, 40.0, 300000.0),
        ellipsoid: {
            radii: new Cesium.Cartesian3(200000.0, 200000.0, 300000.0),
            fill: false,
            outline: true,
            outlineColor: Cesium.Color.YELLOW,
            slicePartitions: 24, //横向切割线
            stackPartitions: 36, //纵向切割线
        },
    });
    // return outlineOnly;
    viewer.zoomTo(outlineOnly);
}
/**添加圆柱 */
function f_AddYZ() {
    var greenCylinder = viewer.entities.add({
        name: "Green cylinder with black outline",
        position: Cesium.Cartesian3.fromDegrees(-100.0, 40.0, 200000.0),
        cylinder: {
            //圆柱
            length: 400000.0,
            topRadius: 200000.0,
            bottomRadius: 200000.0,
            material: Cesium.Color.GREEN,
            outline: true,
            outlineColor: Cesium.Color.DARK_GREEN,
        },
    });
    var redCone = viewer.entities.add({
        name: "Red cone",
        position: Cesium.Cartesian3.fromDegrees(-105.0, 40.0, 200000.0),
        cylinder: {
            //圆锥
            length: 400000.0,
            topRadius: 0.0,
            bottomRadius: 200000.0,
            material: Cesium.Color.RED,
        },
    });
    // return greenCylinder;
    viewer.zoomTo(greenCylinder);
}
/**获取摄像机高度 */
function f_GetCameraHeight() {
    var cameraPos = viewer.camera.position;
    var ellipsoid = viewer.scene.globe.ellipsoid;
    var cartographic = ellipsoid.cartesianToCartographic(cameraPos);
    var height = cartographic.height;
    return height;
}
/**放大 */
function f_ZoomIn() {
    viewer.camera.zoomIn(f_GetCameraHeight() / 2);
}
/**缩小 */
function f_ZoomOut() {
    let hh = f_GetCameraHeight();
    if (hh < 1599999.0) {
        viewer.camera.zoomOut(f_GetCameraHeight() * 1.5);
    }
}
/**全屏 */
function f_FullMap() {
    viewer.camera.setView({
        destination: Cesium.Cartesian3.fromDegrees(113.82, 34.03, 1600000.0),
        orientation: {
            roll: 0.0,
        },
    });
}
/**光照 */
function f_MapLight(e) {
    viewer.scene.Globe.enableLighting = e;
}
/**相机角度 */
function f_camerarote(e) {
    viewer.scene.screenSpaceCameraController.enableRotate = !e;
}
/**获取地图显示范围 */
function f_GetMapRect() {
    let viewerRectangle = viewer.camera.computeViewRectangle();
    let rect = {
        west: ((viewerRectangle.west / Math.PI) * 180).toFixed(6),
        south: ((viewerRectangle.south / Math.PI) * 180).toFixed(6),
        east: ((viewerRectangle.east / Math.PI) * 180).toFixed(6),
        north: ((viewerRectangle.north / Math.PI) * 180).toFixed(6),
    };
    return rect;
}
/**添加飞机模型 */
function f_AddMod(url, x, y, z) {
    f_ClearEntities();
    let position = Cesium.Cartesian3.fromDegrees(x, y, z);
    let heading = Cesium.Math.toRadians(180);
    let pitch = 0;
    let roll = 0;
    let hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
    let orientation = Cesium.Transforms.headingPitchRollQuaternion(
        position,
        hpr
    );
    let entity = viewer.entities.add({
        name: "air",
        position: position,
        orientation: orientation,
        model: {
            uri: url,
            minimumPixelSize: 128,
            maximumScale: 20000,
        },
    });
    // return entity;
    viewer.zoomTo(entity);
}
/**沿路径飞行 */
function f_FlyByPath(triger) {
    if (!triger) {
        f_ClearEntities();
        viewer.clock.clockRange = Cesium.ClockRange.UNBOUNDED;
        viewer.clock.shouldAnimate = false;
        return;
    }
    viewer.clock.shouldAnimate = true;
    let data = [];
    data[0] = [
        { longitude: 116.405419, dimension: 39.918034, height: 0, time: 0 },
        { longitude: 116.2821, dimension: 39.918145, height: 0, time: 40 },
        {
            longitude: 115.497402,
            dimension: 39.344641,
            height: 70000,
            time: 100,
        },
        {
            longitude: 107.942392,
            dimension: 29.559967,
            height: 70000,
            time: 280,
        },
        { longitude: 106.549265, dimension: 29.559967, height: 0, time: 360 },
    ];
    data[1] = [
        { longitude: 116.405419, dimension: 39.918034, height: 0, time: 0 },
        { longitude: 117.034586, dimension: 39.881202, height: 0, time: 40 },
        {
            longitude: 116.340088,
            dimension: 38.842224,
            height: 70000,
            time: 100,
        },
        {
            longitude: 113.489176,
            dimension: 23.464017,
            height: 70000,
            time: 280,
        },
        { longitude: 113.262084, dimension: 23.13901, height: 0, time: 360 },
    ];
    data[2] = [
        { longitude: 118.838979, dimension: 32.073514, height: 0, time: 0 },
        { longitude: 118.438838, dimension: 32.03777, height: 0, time: 40 },
        {
            longitude: 117.802406,
            dimension: 31.91231,
            height: 70000,
            time: 100,
        },
        {
            longitude: 104.043645,
            dimension: 35.993845,
            height: 70000,
            time: 280,
        },
        { longitude: 101.807224, dimension: 36.660972, height: 0, time: 360 },
    ];
    let start = Cesium.JulianDate.fromDate(new Date(2023, 3, 29));
    let stop = Cesium.JulianDate.addSeconds(
        start,
        360,
        new Cesium.JulianDate()
    );
    viewer.clock.startTime = start.clone();
    viewer.clock.currentTime = start.clone();
    viewer.clock.stopTime = stop.clone();
    viewer.clock.multiplier = 10;
    viewer.timeline.zoomTo(start, stop);
    viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP;
    for (let i = 0; i < data.length; i++) {
        let property = computeFlight(start, data[i]);
        let planeModel = viewer.entities.add({
            availability: new Cesium.TimeIntervalCollection([
                new Cesium.TimeInterval({
                    start: start,
                    stop: stop,
                }),
            ]),
            position: property,
            orientation: new Cesium.VelocityOrientationProperty(property),
            model: {
                uri: "3Dmod/Cesium_Air.glb",
                minimumPixelSize: 128,
            },
        });
        if (i == 0) {
            viewer.trackedEntity = planeModel;
        }
    }
}
/**计算飞行 */
function computeFlight(start, source) {
    let property = new Cesium.SampledPositionProperty();
    for (let i = 0; i < source.length; i++) {
        let time = Cesium.JulianDate.addSeconds(
            start,
            source[i].time,
            new Cesium.JulianDate()
        );
        let position = Cesium.Cartesian3.fromDegrees(
            source[i].longitude,
            source[i].dimension,
            source[i].height
        );
        property.addSample(time, position);
    }
    return property;
}
/**视角围绕一点旋转 */
var Exection = null;
function f_LookAtPosition(ops) {
    let position = Cesium.Cartesian3.fromDegrees(ops.lng, ops.lat, ops.height);
    let pitch = Cesium.Math.toRadians(-30);
    let angle = 360 / 30;
    let distance = 5000;
    let startTime = Cesium.JulianDate.fromDate(new Date());
    viewer.clock.startTime = startTime.clone();
    viewer.clock.currentTime = startTime.clone();
    viewer.clock.clockRange = Cesium.ClockRange.CLAMPED;
    viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK;
    let initialHeading = viewer.camera.heading;
    Exection = function TimeExecution() {
        let delTime = Cesium.JulianDate.secondsDifference(
            viewer.clock.currentTime,
            viewer.clock.startTime
        );
        let heading = Cesium.Math.toRadians(delTime * angle) + initialHeading;
        viewer.scene.camera.setView({
            destination: position,
            orientation: {
                heading: heading,
                pitch: pitch,
            },
        });
        viewer.scene.camera.moveBackward(distance);
        if (
            Cesium.JulianDate.compare(
                viewer.clock.currentTime,
                viewer.clock.stopTime
            ) >= 0
        ) {
            viewer.clock.onTick.removeEventListener(Exection);
        }
    };
    viewer.clock.onTick.addEventListener(Exection);
}
function f_ClearTick() {
    if (Exection != null) {
        viewer.clock.onTick.removeEventListener(Exection);
        Exection = null;
    }
}
function f_AddFlashPntByXYH(x, y, h, m_color) {
    class EllipsoidFadeMaterialProperty {
        constructor(color, duration) {
            this._definitionChanged = new Cesium.Event();
            var _color = undefined;
            var _colorSubscription = undefined;
            var color = color;
            var duration = duration;
            var _time = new Date().getTime();
        }
        getType(time) {
            return "EllipsoidFade";
        }
        getValue(time, result) {
            if (!Cesium.defined(result)) {
                result = {};
            }
            result.color = Cesium.Property.getValueOrClonedDefault(
                this._color,
                time,
                Cesium.Color.WHITE,
                result.color
            );

            result.time =
                ((new Date().getTime() - this._time) % this.duration) /
                this.duration;
            return result;
        }
        equals(other) {
            return (
                this === other ||
                (other instanceof EllipsoidFadeMaterialProperty &&
                    Cesium.Property.equals(this._color, other._color))
            );
        }
    }
    Cesium.defineProperties(EllipsoidFadeMaterialProperty.prototype, {
        isConstant: {
            get: function () {
                return false;
            },
        },
        definitionChanged: {
            get: function () {
                return this._definitionChanged;
            },
        },
        color: Cesium.createPropertyDescriptor("color"),
    });
    Cesium.EllipsoidFadeMaterialProperty = EllipsoidFadeMaterialProperty;
    Cesium.Material.EllipsoidFadeType = "EllipsoidFade";
    Cesium.Material.EllipsoidFadeSource =
        "czm_material czm_getMaterial(czm_materialInput materialInput)\n" +
        "{\n" +
        "czm_material material = czm_getDefaultMaterial(materialInput);\n" +
        "material.diffuse = 1.5 * color.rgb;\n" +
        "vec2 st = materialInput.st;\n" +
        "float dis = distance(st, vec2(0.5, 0.5));\n" +
        "float per = fract(time);\n" +
        "if(dis > per * 0.5){\n" +
        "material.alpha = 0.0;\n" +
        "discard;\n" +
        "}else {\n" +
        "material.alpha = color.a  * dis / per / 1.0;\n" +
        "}\n" +
        "return material;\n" +
        "}";
    Cesium.Material._materialCache.addMaterial(
        Cesium.Material.EllipsoidFadeType,
        {
            fabric: {
                type: Cesium.Material.EllipsoidFadeType,
                uniforms: {
                    color: new Cesium.Color(1.0, 0.0, 0.0, 1),
                    time: 0,
                },
                source: Cesium.Material.EllipsoidFadeSource,
            },
            translucent: function (material) {
                return true;
            },
        }
    );

    var big = m_temp_source.entities.add({
        name: "EllipsoidFade",
        position: Cesium.Cartesian3.fromDegrees(x, y, h),
        ellipse: {
            height: 0,
            semiMinorAxis: 6000.0,
            semiMajorAxis: 6000.0,
            material: new Cesium.EllipsoidFadeMaterialProperty(m_color, 2000),
        },
    });
    big.distanceDisplayCondition = new Cesium.DistanceDisplayCondition(
        10000,
        900000
    );

    var sm = m_temp_source.entities.add({
        name: "EllipsoidFade",
        position: Cesium.Cartesian3.fromDegrees(x, y, h),
        ellipse: {
            height: 0,
            semiMinorAxis: 600.0,
            semiMajorAxis: 600.0,
            material: new Cesium.EllipsoidFadeMaterialProperty(m_color, 2000),
        },
    });
    sm.distanceDisplayCondition = new Cesium.DistanceDisplayCondition(1, 10000);
}

function animationline(pos) {
    var primitive = new Cesium.primitive({
        geometryInstances: new Cesium.GeometryInstance({
            geometry: new Cesium.PolylineGeometry({
                positions: pos,
                width: 5,
                vertexFormat: Cesium.PolylineMaterialAppearance.VERTEX_FORMAT,
            }),
            attributes: {
                color: Cesium.ColorGeometryInstanceAttribute.fromColor(
                    new Cesium.Color(1.0, 1.0, 1.0, 1.0)
                ),
            },
        }),
        appearance: new Cesium.PolylineMaterialAppearance({
            material: Cesium.Material.fromType(Cesium.Material.FadeType, {
                repeat: true,
                fadeInColor: Cesium.Color.BLUE.withAlpha(0),
                fadeOutColor: Cesium.Color.WHITE,
                time: new Cesium.Cartesian2(0.0, 0.0),
                fadeDirection: {
                    x: true,
                    y: false,
                },
            }),
        }),
    });
    return primitive;
}
//获取当前相机信息
function f_GetCurCameraInfo() {
    return {
        heading: viewer.scene.camera.heading,
        pitch: viewer.scene.camera.pitch,
        roll: viewer.scene.camera.roll,
        lon: viewer.camera.position.x,
        lat: viewer.camera.position.y,
        height: viewer.camera.position.z,
    };
}
function f_SetMapView(heading, pitch, roll, lon, lat, height) {
    // console.log(heading, pitch, roll, lon, lat, height);
    if (heading) {
        viewer.camera.flyTo({
            destination: new Cesium.Cartesian3(lon, lat, height),
            orientation: {
                // 指向
                heading: heading,
                // 视角
                pitch: pitch,
                roll: roll,
            },
        });
    } else {
        viewer.camera.flyTo({
            //摄像机在 WGS84(世界)中的最终位置坐标或从自上而下的视图中可以看到的矩形
            destination: new Cesium.Cartesian3(
                viewer.camera.position.x,
                viewer.camera.position.y,
                viewer.camera.position.z
            ),
            //包含方向和向上属性或航向、俯仰和滚动属性的物体。默认情况下，方向将指向框架的中心在3D 和负 z 方向在哥伦布视图。
            //上行方向将指向当地北部的3D 和正 y 方向的哥伦布视图。在无限滚动模式下，2D 中不使用定位。
            orientation: {
                heading: Cesium.Math.toRadians(0),
                //   pitch: Cesium.Math.toRadians(-90),
                pitch: viewer.scene.camera.pitch,
                roll: 0.0,
            },
        });
    }
}

/**
 * 根据类型绘制对象
 * @param type point、polyline、polygon
 */
let tempEntities = [];
let braid = null;
function draw(type) {
    mainStore().changePunctuation("type", type);
    let position = [];
    let tempPoints = [];
    // 开启深度检测
    // viewer.scene.globe.depthTestAgainstTerrain = true;
    braid = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    switch (type) {
        case "polyline":
            ElMessage("开始绘制，右键结束绘制！");
            //左键点击操作
            braid.setInputAction(function (click) {
                //调用获取位置信息的接口
                let ray = viewer.camera.getPickRay(click.position);
                position = viewer.scene.globe.pick(ray, viewer.scene);
                tempPoints.push(position);
                let tempLength = tempPoints.length;
                //调用绘制点的接口
                let point = drawPoint(tempPoints[tempPoints.length - 1]);
                tempEntities.push(point);
                if (tempLength > 1) {
                    let pointline = drawPolyline([
                        tempPoints[tempPoints.length - 2],
                        tempPoints[tempPoints.length - 1],
                    ]);
                    tempEntities.push(pointline);
                } else {
                    // tooltip.innerHTML = "请绘制下一个点，右键结束";
                }
            }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
            //右键点击操作
            braid.setInputAction(function (click) {
                if (!tempEntities.length) {
                    ElMessage("已取消绘制！");
                    tempPoints = [];
                    braid.destroy(); //关闭事件句柄
                    braid = null;
                    return;
                } else if (tempEntities.length == 1) {
                    ElMessage("绘制标线至少需要两个点！");
                    return;
                }
                let hierarchy = [];
                tempPoints.forEach((element) => {
                    // 笛卡尔空间直角坐标系转为地理坐标（弧度制）
                    var cartographic =
                        Cesium.Cartographic.fromCartesian(element);
                    // 地理坐标（弧度制）转为经纬度坐标
                    var lat = Cesium.Math.toDegrees(cartographic.latitude);
                    var lng = Cesium.Math.toDegrees(cartographic.longitude);
                    hierarchy.push(lng);
                    hierarchy.push(lat);
                });
                mainStore().changePunctuation("title", "添加线标绘");
                mainStore().changePunctuation("position", hierarchy);
                mainStore().changePunctuation("position3d", tempPoints);
                mainStore().changePunctuation("show", true);
                drawPolylines();
                tempPoints = [];
                braid.destroy(); //关闭事件句柄
                braid = null;
            }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
            break;
        case "polygon":
            ElMessage("开始绘制，右键结束绘制！");
            //左键点击操作
            braid.setInputAction(function (click) {
                //调用获取位置信息的接口
                let ray = viewer.camera.getPickRay(click.position);
                position = viewer.scene.globe.pick(ray, viewer.scene);
                tempPoints.push(position);
                let tempLength = tempPoints.length;
                //调用绘制点的接口
                let point = drawPoint(position);
                tempEntities.push(point);
                if (tempLength > 1) {
                    let pointline = drawPolyline([
                        tempPoints[tempPoints.length - 2],
                        tempPoints[tempPoints.length - 1],
                    ]);
                    tempEntities.push(pointline);
                } else {
                    // tooltip.innerHTML = "请绘制下一个点，右键结束";
                }
            }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
            //右键点击操作
            braid.setInputAction(function (click) {
                let cartesian = viewer.camera.pickEllipsoid(
                    click.position,
                    viewer.scene.globe.ellipsoid
                );
                if (cartesian) {
                    let tempLength = tempPoints.length;
                    if (!tempLength) {
                        ElMessage("已取消绘制！");
                        braid.destroy(); //关闭事件句柄
                        braid = null;
                        return;
                    }
                    if (tempLength < 3) {
                        alert("请选择3个以上的点再执行闭合操作命令");
                    } else {
                        //闭合最后一条线
                        let pointline = drawPolyline([
                            tempPoints[tempPoints.length - 1],
                            tempPoints[0],
                        ]);
                        tempEntities.push(pointline);
                        let hierarchy = [];
                        tempPoints.forEach((element) => {
                            // 笛卡尔空间直角坐标系转为地理坐标（弧度制）
                            var cartographic =
                                Cesium.Cartographic.fromCartesian(element);
                            // 地理坐标（弧度制）转为经纬度坐标
                            var lat = Cesium.Math.toDegrees(
                                cartographic.latitude
                            );
                            var lng = Cesium.Math.toDegrees(
                                cartographic.longitude
                            );
                            hierarchy.push(lng);
                            hierarchy.push(lat);
                        });
                        tempEntities.push(tempPoints);
                        mainStore().changePunctuation("title", "添加面标绘");
                        mainStore().changePunctuation("position", hierarchy);
                        mainStore().changePunctuation("position3d", tempPoints);
                        mainStore().changePunctuation("show", true);
                        drawPolygon();
                        braid.destroy(); //关闭事件句柄
                        braid = null;
                    }
                }
            }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
            break;
        case "stereoscopic":
            ElMessage("左键选择起点，右键选择终点！");
            mainStore().changePunctuation("title", "添加立体字");
            mainStore().changePunctuation("position", [[], []]);
            mainStore().changePunctuation("show", true);
            braid.setInputAction(function (click) {
                f_ClearEntities(1100);
                //调用获取位置信息的接口
                let ray = viewer.camera.getPickRay(click.position);
                position = viewer.scene.globe.pick(ray, viewer.scene);
                let cartographic = Cesium.Cartographic.fromCartesian(position);
                let x = Cesium.Math.toDegrees(cartographic.latitude);
                let y = Cesium.Math.toDegrees(cartographic.longitude);
                //调用绘制点的接口
                let point = drawPoint(position, 1100);
                let dingwei = mainStore().$state.punctuation.position[1];
                mainStore().changePunctuation("position", [[y, x], dingwei]);
            }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
            braid.setInputAction(function (click) {
                f_ClearEntities(1101);
                let ray = viewer.camera.getPickRay(click.position);
                position = viewer.scene.globe.pick(ray, viewer.scene);
                let cartographic = Cesium.Cartographic.fromCartesian(position);
                let x = Cesium.Math.toDegrees(cartographic.latitude);
                let y = Cesium.Math.toDegrees(cartographic.longitude);
                let point = drawPoint(position, 1101);
                let dingwei = mainStore().$state.punctuation.position[0];
                mainStore().changePunctuation("position", [dingwei, [y, x]]);
            }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
            break;
    }
}
function drawPoint(position, type) {
    return viewer.entities.add({
        name: "点几何对象",
        position: position,
        type: type ? type : 1100,
        point: {
            color: Cesium.Color.white,
            pixelSize: 10,
            disableDepthTestDistance: Number.POSITIVE_INFINITY,
            heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
        },
    });
}
function drawPolylines(embryo, code, type) {
    f_ClearEntities(1100);
    return viewer.entities.add({
        name: embryo ? embryo.name : "折线",
        type: embryo ? type : 1100,
        code,
        embryo,
        polyline: {
            positions: Cesium.Cartesian3.fromDegreesArray(
                embryo && embryo.position
                    ? JSON.parse(embryo.position)
                    : mainStore().$state.punctuation.position
            ),
            width: embryo ? embryo.lineWidth : 2.0,
            material: embryo
                ? colorConvert(embryo.lineColor)
                : Cesium.Color.GOLD,

            clampToGround: true,
        },
    });
}
function drawPolyline(positions, code, type) {
    let hierarchy = [];
    positions.forEach((element) => {
        // 笛卡尔空间直角坐标系转为地理坐标（弧度制）
        var cartographic = Cesium.Cartographic.fromCartesian(element);
        // 地理坐标（弧度制）转为经纬度坐标
        var lat = Cesium.Math.toDegrees(cartographic.latitude);
        var lng = Cesium.Math.toDegrees(cartographic.longitude);
        hierarchy.push(lng);
        hierarchy.push(lat);
    });

    if (positions.length < 1) return;
    return viewer.entities.add({
        name: "线几何对象",
        type: 1100,
        polyline: {
            positions: positions,
            width: 5.0,
            material: new Cesium.PolylineGlowMaterialProperty({
                color: Cesium.Color.GOLD,
            }),
            // depthFailMaterial: new Cesium.PolylineGlowMaterialProperty({
            //     color: Cesium.Color.GOLD,
            // }),
            clampToGround: true,
        },
    });
}
function drawPolygon(embryo, code, type) {
    f_ClearEntities(1100);
    let polyCenter = Cesium.BoundingSphere.fromPoints(
        mainStore().$state.punctuation.position3d
    ).center;
    let Polygon = viewer.entities.add({
        name: embryo ? embryo.name : "几何面",
        type: embryo ? type : 1100,
        code,
        embryo,
        polygon: {
            hierarchy: Cesium.Cartesian3.fromDegreesArray(
                embryo && embryo.position
                    ? JSON.parse(embryo.position)
                    : mainStore().$state.punctuation.position
            ),
            height: 0,
            material: embryo
                ? colorConvert(embryo.planeColor)
                : new Cesium.Color.fromCssColorString("#FFD700").withAlpha(0.2),
            outline: embryo && embryo.frameWidth ? true : false,
            outlineColor: embryo
                ? colorConvert(embryo.frameColor)
                : Cesium.Color.RED,
            outlineWidth: embryo && embryo.frameWidth ? embryo.frameWidth : 1,
            heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
        },
    });
    return Polygon;
}

/**
 * 开关地形
 * @param {Boolean} show
 */
function toggleTerrain(show, x) {
    let scene = x ? viewer2.scene : viewer.scene;
    if (show) {
        scene.terrainProvider = Cesium.createWorldTerrain({
            requestWaterMask: true,
            requestVertexNormals: true,
        });
    } else {
        scene.terrainProvider = new Cesium.EllipsoidTerrainProvider({});
    }
}

function f_Add3DText(text, minHight, arrmxy, color) {
    var maxHight = minHight;
    var mxy = arrmxy;
    var dis = getSpaceDistance([mxy[0], mxy[1]], [mxy[2], mxy[3]]);
    //var text = "郑州景观地理空间信息研究院";
    //计算每个字多少米;
    var m_wid = dis / text.length;
    maxHight = minHight + m_wid;
    return viewer.entities.add({
        type: "3DText",
        wall: {
            positions: Cesium.Cartesian3.fromDegreesArray(mxy),
            minimumHeights: [minHight, minHight],
            maximumHeights: [maxHight, maxHight],
            material: new Cesium.ImageMaterialProperty({
                image: drawText(512, text),
                transparent: true,
                color: color,
            }),
        },
    });
}
function getSpaceDistance(satrt0, end0) {
    var satrt = Cesium.Cartographic.fromDegrees(satrt0[0], satrt0[1], 0);
    var end = Cesium.Cartographic.fromDegrees(end0[0], end0[1], 0);
    var geodesic = new Cesium.EllipsoidGeodesic();
    geodesic.setEndPoints(satrt, end);
    var distance = geodesic.surfaceDistance;
    return distance;
}

function textLength(text) {
    let len = 0;
    let reg = /^[0-9a-zA-Z_]{1,}$/;
    for (let index = 0; index < text.length; index++) {
        let c = text.charAt(index);
        // if (Number(c)) {
        //     len += 0.5;
        // }
        if (reg.test(c)) {
            // console.log(c);
            len += 0.5;
        } else {
            len++;
        }
    }
    return len;
    // return Math.ceil(len);  //向下取整
    // return Math.floor(len); //向上取整
}
function drawText(fontSize, text) {
    // console.log(textLength(text + ""));
    var c = document.createElement("canvas");
    const d = textLength(text + "") * fontSize;
    c.width = d;
    c.height = fontSize;
    var ctx = c.getContext("2d");
    ctx.fillStyle = "#ffffff";
    ctx.font = "bold " + fontSize + "px 微软雅黑"; //设置字体
    ctx.textBaseline = "hanging"; //在绘制文本时使用的当前文本基线
    //绘制文本
    ctx.fillText(text, 0, 0);
    return c;
}
function f_Add3DTextArrys() {
    f_Add3DText(
        "郑州市",
        200,
        [113.5334268837, 34.7485981144, 113.6334268837, 34.7485981144],
        Cesium.Color.RED
    );
    f_Add3DText(
        "洛阳市",
        200,
        [112.3434812372, 34.6664649939, 112.4434812372, 34.6664649939],
        Cesium.Color.RED
    );
    f_Add3DText(
        "偃师区",
        200,
        [112.7667386784, 34.7262323943, 112.8189311198, 34.7262323943],
        Cesium.Color.ORANGERED
    );
    f_Add3DText(
        "巩义市",
        200,
        [112.9843010977, 34.7466861204, 113.0364935, 34.7466861204],
        Cesium.Color.ORANGERED
    );
    f_Add3DText(
        "上街区",
        200,
        [113.2559020679, 34.8160596432, 113.3080945, 34.8160596432],
        Cesium.Color.ORANGERED
    );
    f_Add3DText(
        "荥阳市",
        200,
        [113.3639676676, 34.7770654418, 113.4161601, 34.7770654418],
        Cesium.Color.ORANGERED
    );
}
function f_Add3DStereoscopic(embryo, code, type) {
    f_ClearEntities(1100);
    f_ClearEntities(1101);
    let minHight = 200;
    let maxHight = minHight;
    let position = mainStore().$state.punctuation.position;
    if (embryo.position) position = JSON.parse(embryo.position);
    let x = toRaw(position[0]);
    let y = toRaw(position[1]);
    let dis = getSpaceDistance(x, y);
    let m_wid = dis / embryo.name.length;
    maxHight = minHight + m_wid;
    return viewer.entities.add({
        type,
        code,
        embryo,
        wall: {
            positions: Cesium.Cartesian3.fromDegreesArray([
                x[0],
                x[1],
                y[0],
                y[1],
            ]),
            minimumHeights: [minHight, minHight],
            maximumHeights: [maxHight, maxHight],
            material: new Cesium.ImageMaterialProperty({
                image: drawText(512, embryo.name),
                transparent: true,
                color: colorConvert(embryo.stereoscopicColor),
            }),
        },
    });
}
async function f_AddPyramid(embryo) {
    f_ClearEntities(1100);
    if (!embryo) return;
    let polyCenter = null;
    if (embryo.type == 4)
        polyCenter = Cesium.Cartesian3.fromDegrees(112.659462, 34.566414, 1000);
    if (embryo.type == 3)
        polyCenter = Cesium.Cartesian3.fromDegrees(112.940226, 34.623979, 20);
    if (embryo.type == 2)
        polyCenter = Cesium.Cartesian3.fromDegrees(113.133221, 34.691088, 20);
    if (embryo.type == 1)
        polyCenter = Cesium.Cartesian3.fromDegrees(113.357487, 34.692586, 20);

    let hpr = new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(180), 0, 0);
    let orientation = Cesium.Transforms.headingPitchRollQuaternion(
        polyCenter,
        hpr
    );
    let entity = viewer.entities.add({
        name: embryo.name,
        type: 1100,
        position: polyCenter,
        // orientation: orientation,    //方向
        // model: {
        //     uri: "./3Dmod/q.glb",
        //     // uri: "./3Dmod/zhui.glb",
        //     minimumPixelSize: 48,
        //     maximumScale: 100000,
        //     scale: 1.0,
        //     distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
        //         0,
        //         150000
        //     ),
        // },
        label: {
            text: embryo.name,
            font: "20px 微软雅黑",
            fillColor: Cesium.Color.RED,
            pixelOffset: new Cesium.Cartesian2(0, -60),
            outlineColor: Cesium.Color.WHITE,
            outlineWidth: 5,
            style: Cesium.LabelStyle.FILL_AND_OUTLINE,
            verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
                0,
                150000
            ),
        },
    });
    let position = Cesium.Cartesian3.fromDegrees(112.659462, 34.566414, 0);
    let hpRoll = new Cesium.HeadingPitchRoll(
        Cesium.Math.toRadians(90),
        0,
        Cesium.Math.toRadians(0)
    );
    let m = Cesium.Transforms.eastNorthUpToFixedFrame(
        Cesium.Cartesian3.fromDegrees(112.659462, 34.566414, 0)
    );
    let m1 = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(-90));
    Cesium.Matrix4.multiplyByMatrix3(m, m1, m); 
    viewer.scene.primitives.add(Cesium.Model.fromGltf({
        url: "./3Dmod/zhui.glb",
        modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame(position, hpRoll),
        // modelMatrix: m,
        show: true,                     // default
        scale: 3.0,
        maximumScale: 1
    }))
    
    const primitives = viewer.scene.primitives;
    const length = primitives.length;
    for (let i = 0; i < length; ++i) {
    const p = primitives.get(i);
        console.log(p);
    }
    return entity;
}

import colors1 from "../assets/cesiumcss/colors1.png";
function liudong() {
    let center = { lon: 113.4868202825309, lat: 34.69790455463026 };
    let cities = [{ lon: 112.49281700209367, lat: 34.55678905515026 }];
    let positions = JSON.parse(
        "[112.61417168736487,34.95329455243536,112.90338060161486,34.959566663503374,113.14778747211899,34.96904529746231,112.75320800438612,34.824216147854024]"
    );
    fluidPolyline.liudongxian(
        viewer,
        Cesium.Color.RED,
        colors1,
        3000,
        center,
        cities
    );
    fluidPolylinetrend.liudongxian(
        viewer,
        Cesium.Color.ORANGE,
        colors1,
        2000,
        positions
    );
}
window.liudong = liudong;
export default {
    toggleTerrain,
    layset,
    laysetShow,
    layseAlpha,
    mapset,
    setviewer,
    f_LoadTile,
    remove3Dtile,
    f_AddPoi,
    f_AddIconLabel,
    f_AddDimension,
    entitiesShow,
    f_AddPolyLine,
    f_Township,
    fwqIconAdd,
    f_AddpolylineVolume,
    f_AddPolyCustom,
    f_AddReg,
    measureLine,
    mesurePolygon,
    f_creatwall,
    f_ShowMapModel,
    f_AddZL,
    f_AddBall,
    f_AddYZ,
    f_ZoomIn,
    f_ZoomOut,
    f_FullMap,
    f_ClearEntities,
    flyto,
    f_MapLight,
    f_camerarote,
    f_GetMapRect,
    f_AddMod,
    f_FlyByPath,
    f_ClearTick,
    f_LookAtPosition,
    Zoomto,
    f_AddFlashPntByXYH,
    animationline,
    addmaplayer,
    GDlkmap,
    f_Setmap,
    f_GetCurCameraInfo,
    f_SetMapView,
    draw,
    f_Add3DStereoscopic,
    f_Add3DTextArrys,
    drawPolylines,
    drawPolygon,
    f_ShowGridMap,
    f_AddPyramid,
    cehis,
    liudong,
};
